package tcln.sors.model.core.criteria;

import java.util.Date;
import java.util.List;

/**
 * Common interface for all search criteria needed for a search method.
 * 
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public interface SearchCriteria {

    /**
     * Adds a search criterion on a given property using conjunction operator AND.
     * 
     * @param property
     *            Property name. Property expressions, e.g. "product.name", are supported.
     * @param operator
     *            One of the supported operators.
     * @param values
     *            All possible values, depending on given operator.
     * @return Current instance.
     */
    SearchCriteria add(String property, SearchOperator operator, String... values);
    
    /**
     * Adds a search criterion on a given property using conjunction operator AND.
     * 
     * @param property
     *            Property name. Property expressions, e.g. "product.name", are supported.
     * @param operator
     *            One of the supported operators.
     * @param values
     *            All possible values, depending on given operator.
     * @return Current instance.
     */
    SearchCriteria add(String property, SearchOperator operator, Date... values);
    
    /**
     * Adds a search criterion on a given property using conjunction operator AND.
     * 
     * @param property
     *            Property name. Property expressions, e.g. "product.name", are supported.
     * @param operator
     *            One of the supported operators.
     * @param values
     *            All possible values, depending on given operator.
     * @return Current instance.
     */
    SearchCriteria add(String property, SearchOperator operator, Number... values);
    
    /**
     * Adds a search criterion on a given property using conjunction operator AND.
     * 
     * @param property
     *            Property name. Property expressions, e.g. "product.name", are supported.
     * @param operator
     *            One of the supported operators.
     * @param values
     *            All possible values, depending on given operator.
     * @return Current instance.
     */
    SearchCriteria add(String property, SearchOperator operator, Enum<?>... values);

    /**
     * Adds a search criterion.
     * 
     * @param criterion
     * @return
     */
    SearchCriteria add(SearchCriterion criterion);

    /**
     * Returns all criterions.
     * 
     * @return A new list containing all criterions.
     */
    List<SearchCriterion> getCriterions();

    /**
     * Finds out all {@link SearchCriterion}s for given property name.
     * 
     * @param property
     * @return All matching criteria or empty list.
     */
    List<SearchCriterion> findCriterions(String property);

    /**
     * Gets a single {@link SearchCriterion} for given property. If there are more than 1 criterion objects for given
     * property, a runtime exception occurs.
     * 
     * @param property
     * @return Criterion for given property. If there is no criterion, return <code>null</code>. If there are more than
     *         1 criteria, a runtime exception is raised.
     * @throws IllegalStateException
     *             if there are more than 1 criterion objects for given property
     */
    SearchCriterion getCriterion(String property);

    /**
     * Clears all entered criteria.
     */
    void clear();
}
